#include "compat.h"

#ifdef _WIN32
#   include <Windows.h>
#endif

#ifdef COMPAT_TIMERS
    LINKAGE("C") int clock_gettime(clockid_t clk_id, struct timespec *tp)
    {
        FILETIME filetime;
        GetSystemTimeAsFileTime(&filetime);
        int64_t winepoch;
        memcpy(&winepoch, &filetime, sizeof(winepoch));
        tp->tv_nsec = (winepoch % 10000000) * 100;
        tp->tv_sec = (winepoch / 10000000) - 11644473600;
        return 0;
    }
#endif

#ifdef COMPAT_MEMALIGN
    LINKAGE("C") int posix_memalign(void **memptr, size_t alignment, size_t size)
    {
        *memptr = _aligned_malloc(size, alignment);
        if (*memptr) {
            return 0;
        }
        else {
            return errno;
        }
    }
#endif

#ifdef COMPAT_UNIX
    LINKAGE("C") uid_t geteuid(void)
    {
#       ifdef _WIN32
            return 0;
#       else
#           error geteuid not implemented
#       endif
    }

    LINKAGE("C") gid_t getegid(void)
    {
#       ifdef _WIN32
            return 0;
#       else
#           error geteuid not implemented
#       endif
    }
#endif

#include <string.h>
#if _POSIX_C_SOURCE < 1
    char *strtok_r(
            char *str,
            const char *const delim,
            char **const saveptr)
    {
        if (!str) {
            str = *saveptr;
        }
        size_t first;
        while (0 == (first = strcspn(str, delim))) {
            if (str[first] == '\0') {
                return NULL;
            }
            str += 1;
        }
        *saveptr = &str[first];
        return str;
    }
#endif

LINKAGE("C") int posix_fadvise(
        int fd VARATTR_UNUSED,
        int64_t offset VARATTR_UNUSED,
        int64_t len VARATTR_UNUSED,
        int advice VARATTR_UNUSED)
{
    return 0;
}

int fseek64(FILE *stream, int64_t offset, int whence)
{
#   if _FILE_OFFSET_BITS == 64
        return fseeko(stream, offset, whence);
#   elif defined(_WIN32)
        return _fseeki64(stream, offset, whence);
#   else
#       error "off_t must be 64 bits"
#   endif
}

int64_t ftell64(FILE *stream)
{
#   if _FILE_OFFSET_BITS == 64
        return ftello(stream);
#   elif defined(_WIN32)
        return _ftelli64(stream);
#   else
#       error "off_t must be 64 bits"
#   endif
}

#ifndef _LARGEFILE64_SOURCE
	int64_t lseek64(int fd, int64_t offset, int origin)
	{
		return _lseeki64(fd, offset, origin);
	}
#endif
